package ee.siimkaspar.subjects.service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Transactional;

import com.opensymphony.xwork2.validator.ValidationException;

import ee.siimkaspar.subjects.model.ModelInterface;


@Transactional
public class BaseService {

    private EntityManager entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }
	
	public <T extends ModelInterface> T save(T ob) throws ValidationException {
        if (ob == null) {
            throw new IllegalArgumentException("Object you are trying to save is not set.");
        }
        if (!ob.validate()) {
        	return null;
        }
        if (ob.getId() == null) {
            getEntityManager().persist(ob);
            Logger.getLogger(BaseService.class).debug("Added new: " + ob);
        } else {
            getEntityManager().merge(ob);
            Logger.getLogger(BaseService.class).debug("Updated : " + ob);
        }
        return ob;

    }

    public <T extends ModelInterface> void remove(T ob) {
        Logger.getLogger(getClass()).debug("Deleting object: " + ob);
        if (ob != null && ob.getId() != null) {
            T attached = getEntityManager().merge(ob);
            getEntityManager().remove(attached);
        } else {
            throw new IllegalArgumentException("Required parameter or its id is null");
        }
    }

    @SuppressWarnings("unchecked")
    public <T extends ModelInterface> T reAttach(T ob, Class<T> cl) throws Exception {
        if (ob != null && ob.getId() != null) {

            Query q = getEntityManager().createQuery("select o from " + cl.getSimpleName() + " o where id=" + ob.getId());
            return (T) q.getSingleResult();

        } else {
            throw new IllegalArgumentException("Required parameter or its id is null");
        }
    }

    public <T extends ModelInterface> T findObject(Class<T> classs, Number identificator) {
        return getEntityManager().find(classs, identificator);
    }
}
